<template>
  <div class="page-wrapper">
    <h2 class="page-title">Tab页管理</h2>

    <!-- 每个组 -->
    <div v-for="(group,idx) in groups" :key="idx" class="group">
      <div class="group-header">
        <!-- 编辑模式：小输入框 -->
        <el-input
            v-if="group.editing"
            v-model="group.inputValue"
            size="small"
            class="group-title-input"
            placeholder="输入标题"
            :style="{ width: '160px' }"
            @blur="group.editing = false"
            @keyup.enter="group.editing = false"
            ref="editInput"
        />

        <!-- 普通显示：可点击切换 -->
        <span
            v-else
            class="group-title"
            @click="
            group.editing = true;
            /* 等下一帧 DOM 更新后再聚焦输入框 */
            nextTick(() => {
              const input = $refs.editInput?.[$refs.editInput.length-1];
              input && input.focus();
            })
          "
        >
          {{ group.inputValue || '输入标题' }}
        </span>

        <el-icon>
          <Edit/>
        </el-icon>
        <el-link size="small" class="ml-1" type="info" @click="removeGroup(idx)">删除标题</el-link>
      </div>

      <!-- 根节点：自身输入框隐藏 -->
      <NodeEditor :node="group" :hideSelfInput="true"/>
    </div>

    <el-link type="primary" size="small" @click="addGroup">新增标题</el-link>
    <el-divider/>
  </div>

  <div class="form-actions">
    <button class="btn-cancel" @click="clearAll">清空</button>
    <button class="btn-repull" @click="load">重新拉取</button>
    <button class="btn-save" @click="submit">保存</button>
  </div>
</template>

<script setup>
import {reactive, ref, nextTick, onMounted} from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus'
import NodeEditor from './component/NodeEditor.vue'

/* ======================================================== 公共工具 ==================================================================== */
const API_BASE = '/api/v1'
const TOKEN = localStorage.getItem('token')

async function api(url, opt = {}) {
  return fetch(`${API_BASE}${url}`, {
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${TOKEN}`,
      ...(opt.headers || {})
    },
    ...opt
  }).then(r => r.json())
}

function toast(msg) {
  alert(msg) // 简易提示，可替换成自定义弹框
}

/********************
 * 工具函数
 ********************/
function createNode(level = 1) {
  return reactive({level, inputValue: '', options: []})
}

function createGroup() {
  // ⭐ 壳节点，level = 0（不会在树里显示）
  const shell = reactive({level: 0, inputValue: '', options: []})
  // 真正的一级节点
  const root = createNode(1)
  shell.options.push(root)
  shell.editing = false
  return shell
}

/* ---------- 转换后端结点 ---------- */
function fromServerNode(sv) {
  const node = createNode(Number(sv.level) || 1)
  node.inputValue = sv.inputValue ?? sv.name ?? ''
  const kids = sv.options ?? sv.children ?? []
  node.options = Array.isArray(kids) ? kids.map(fromServerNode) : []
  return node
}

function fromServerGroup(sg) {
  const shell = reactive({level: 0, inputValue: sg.inputTitle ?? '', options: [], editing: false})
  shell.options.push(fromServerNode(sg))   // 一级节点
  return shell
}

/* 数据 */
const groups = reactive([createGroup(), createGroup()])

/* 拉取并渲染 */
const load = async () => {
  try {
    const res = await api('/all_scenes')
    const list = Array.isArray(res) ? res : res.data
    if (!Array.isArray(list)) throw new Error('格式不符')
    groups.splice(0, groups.length, ...list.map(fromServerGroup))
    ElMessage.success('重新拉取成功')
  } catch (e) {
    ElMessage.error('重新拉取失败：' + e.message)
  }
}

/* 方法 */
const addGroup = () => groups.push(createGroup())

const removeGroup = (idx) => {
  ElMessageBox.confirm(
      '确定删除整个标题及其所有子项吗？',
      '提示',
      {type: 'warning'}
  ).then(() => {
    groups.splice(idx, 1);
  }).catch(() => {
  });
}

const clearAll = () => {
  ElMessageBox.confirm(
      '确定要清空全部标题及其节点吗？',
      '提示', {type: 'warning'}
  ).then(() => {
    groups.splice(0, groups.length, createGroup(), createGroup())
    ElMessage.success('清空成功')
  }).catch(() => {/* 用户点取消 */
  })
}

const submit = async () => {
  const payload = JSON.parse(JSON.stringify(groups))
  const res = await api('/all_scenes', {method: 'POST', body: JSON.stringify(payload)})
  if (res.code === 0) {
    ElMessage.success('全量场景结构保存成功')
  } else {
    ElMessage.error(res.message || '保存失败')
  }
}

/* 让外层能用到 nextTick 聚焦 */
onMounted(load)

// 暴露方法给父组件
defineExpose({
  submit,
  load,
  clearAll
})
</script>

<style scoped>
/* 从 control.css 中提取相关样式 */
.page-wrapper {
  max-width: 860px;
  margin: 32px auto;
  padding: 0 16px;
  background: transparent;
  box-shadow: none;
  border-radius: 0;
}

.page-title {
  font-size: 20px;
  font-weight: 600;
  margin-bottom: 24px;
}

.group {
  margin-bottom: 40px;
}

.group-header {
  display: flex;
  align-items: center;
  margin-bottom: 12px;
}

.group-title {
  font-weight: 500;
  color: #606266;
  margin-right: 4px;
}

.group-header .el-icon {
  font-size: 14px;
  margin-right: auto;
  color: #909399;
}

.group-title-input {
  margin-right: 4px;
}

/* 标题文字 */
.group-title,
.group-title-input {
  font-size: 20px;
  font-weight: 600;
}

.ml-1 {
  margin-left: 4px;
}

.form-actions {
  margin: 40px 0 80px;
  display: flex;
  gap: 40px;
  justify-content: center;
}

.btn-cancel {
  width: 120px;
  height: 40px;
  background: #fff;
  color: #000;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  font-size: 18px;
}

.btn-repull {
  width: 120px;
  height: 40px;
  background: #fff;
  color: #1890ff;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  font-size: 18px;
}

.btn-save {
  width: 240px;
  height: 40px;
  background: #1890ff;
  color: #fff;
  border: 1px solid #1890ff;
  border-radius: 4px;
  font-size: 18px;
}

button:hover {
  opacity: .85;
}
</style>